home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’94
/
[√] Distribution Restricted!
/
Steve Sisak
/
TMFutures
/
FuturesDemo.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-26
|
6KB
|
222 lines
#include "FuturesDemo.h"
#include "Futures.h"
#include "Threads.h"
#include "AEThreads.h"
#include <PPCToolBox.h>
#include <EPPC.h>
#include <AppleEvents.h>
#include <string.h>
AEDesc gNullDesc; // A null descriptor record
AEAddressDesc gSelfAddress; // A self-addressed address descriptor record
ProcessSerialNumber gSelfPSN; // This application's psn
#pragma segment handlers
pascal OSErr HandlePing(AppleEvent question, AppleEvent answer, long /*handlerRefcon*/)
{
char* stringPtr;
char stringBuffer[100];
long actualSize;
DescType actualType;
OSErr theErr;
EventRecord evt;
// Beep to indicate that the question was received
while (EventAvail(everyEvent, &evt))
{
YieldToAnyThread();
}
SysBeep(120);
// Extract a string from the question.
theErr = AEGetParamPtr(&question, 'qstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
// Load a string into the answer.
stringPtr = "I’m just fine.";
theErr = AEPutParamPtr(&answer, 'rstr', 'TEXT', stringPtr, strlen(stringPtr));
return(noErr);
}
pascal OSErr HandlePing1(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
{
OSErr theErr;
TargetID theTargetID;
PortInfoRec thePortInfo;
AEAddressDesc theAddressDesc;
AppleEvent question;
AppleEvent answer;
char* stringPtr;
char stringBuffer[100];
long actualSize;
DescType actualType;
long i;
// Get the target address of the other process
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
// Start the thread that pings
for (i=0; i<30; i++)
{
YieldToAnyThread();
// Build an AppleEvent question that is addressed to the user selected target
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
// Load a string into the question.
stringPtr = "Hello server, how are you doing?";
theErr = AEPutParamPtr(&question, 'qstr', 'TEXT', stringPtr, strlen(stringPtr));
// Ask the question
theErr = Ask(&question, &answer);
// If the answer is not a future so soon after ask, something is probably wrong.
// if (!IsFuture(&answer)) Debugger();
// Extract a string from the answer. This will cause the thread to block until the answer is received.
theErr = AEGetParamPtr(&answer, 'rstr', 'TEXT', &actualType, (Ptr) &stringBuffer, sizeof(stringBuffer)-1, &actualSize);
// If the answer is still a future after retrieving a string from the answer, something is definitely wrong.
// if (IsFuture(&answer)) Debugger();
// Dispose of the answer and the question.
theErr = AEDisposeDesc(&answer);
theErr = AEDisposeDesc(&question);
}
// Dispose of the address descriptor now that the thread no longer needs it.
theErr = AEDisposeDesc(&theAddressDesc);
return theErr;
}
pascal OSErr HandlePing2(AppleEvent /*event*/, AppleEvent /*reply*/, long /*handlerRefcon*/)
{
OSErr theErr;
TargetID theTargetID;
PortInfoRec thePortInfo;
AEAddressDesc theAddressDesc;
AEAddressDesc theAddressDesc2;
AppleEvent question;
AppleEvent question2;
AppleEvent answer;
AppleEvent answer2;
long i;
// Get the target addresses of the two processes
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc);
theErr = PPCBrowser("\p", "\p", false, &theTargetID.location, &thePortInfo, nil, "\p");
theTargetID.name = thePortInfo.name;
theErr = AECreateDesc(typeTargetID, (Ptr) &theTargetID, sizeof(TargetID), &theAddressDesc2);
// Start the thread that pings
for (i=0; i<30; i++)
{
YieldToAnyThread();
// Build the questions.
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc, kAutoGenerateReturnID, kAnyTransactionID, &question);
theErr = AECreateAppleEvent(kSillyEventClass, kPingEvent, &theAddressDesc2, kAutoGenerateReturnID, kAnyTransactionID, &question2);
// Ask the questions.
theErr = Ask(&question, &answer);
theErr = Ask(&question2, &answer2);
// Block until the answers become real.
theErr = BlockUntilReal(&answer);
theErr = BlockUntilReal(&answer2);
// Dispose of the answers and the questions.
theErr = AEDisposeDesc(&answer);
theErr = AEDisposeDesc(&answer2);
theErr = AEDisposeDesc(&question);
theErr = AEDisposeDesc(&question2);
}
// Dispose of the address descriptor now that the thread no longer needs it.
theErr = AEDisposeDesc(&theAddressDesc);
theErr = AEDisposeDesc(&theAddressDesc2);
return noErr;
}
#pragma segment Main
void SendSimpleAEvt(AEEventClass theAEEventClass, AEEventID theAEEventID)
{
AppleEvent myAppleEvent, reply;
// Create the Apple Event.
AECreateAppleEvent(theAEEventClass, theAEEventID, &gSelfAddress,
kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
// Send the Apple Event.
AESend(&myAppleEvent, &reply, kAENoReply, kAENormalPriority,
kAEDefaultTimeout, nil, nil);
AEDisposeDesc(&myAppleEvent); // Dispose of the Apple Event.
}
pascal void InitFuturesDemo(void)
{
gSelfPSN.highLongOfPSN = 0;
gSelfPSN.lowLongOfPSN = kCurrentProcess; //* Use this instead of GetCurrentProcess *//
AECreateDesc(typeProcessSerialNumber,(Ptr)&gSelfPSN,sizeof(ProcessSerialNumber),&gSelfAddress);
gNullDesc.descriptorType = typeNull; // Initialize the global null descriptor record.
gNullDesc.dataHandle = nil;
// Initialize the futures package
InitFutures();
// Install a handler for the ping messages in AppleEvents, so that when we receive these events, this routine will be called
#if 0
AEInstallEventHandler(kSillyEventClass, kPingEvent, NewAEEventHandlerProc(HandlePing), 0, false);
#else
AEInstallThreadedEventHandler(kSillyEventClass, kPingEvent, (AEEventHandlerProcPtr) &HandlePing, 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
#endif
AEInstallThreadedEventHandler(kSillyEventClass, kPing1Event, (AEEventHandlerProcPtr) &HandlePing1, 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
AEInstallThreadedEventHandler(kSillyEventClass, kPing2Event, (AEEventHandlerProcPtr) &HandlePing2, 0,
kCreateIfNeeded+kFPUNotNeeded, 0);
}
pascal void CleanupFuturesDemo(void)
{
AEDisposeDesc(&gSelfAddress); // Dispose of my self-addressed descriptor.
}